﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once
#include "GnufAsynchronousTaskManager.h"
#include "GcmpUiBase.h"

namespace gnuf {
    
    /// \brief AsynchronousDeferredTask intends to defer executing the task. 
    /// This kind of task is not really asynchronous. It is executed only when
    /// OS is idle. That is, OS just allocates a time segment for executing 
    /// this kind of task.
    ///
    /// \see AsynchronousThreadTask.
    ///

    class GCMP_UIBASE_EXPORT AsynchronousDeferredTask
        : public AsynchronousTask
    {
    public:
        enum class EPriority
        {
            eHigh,
            eNormal,
            eLow
        };

        AsynchronousDeferredTask(
            AsynchronousDeferredTask::EPriority,
            AsynchronousTask::ESubtype,
            IAsynchronousTaskHandler * pHandler = nullptr);
        virtual ~AsynchronousDeferredTask();

        AsynchronousDeferredTask::EPriority priority() const { return m_priority; }

        // Once invalid, this task does not get executed, anytime.
        // Note that this change is not reversible. No any method
        // to set back to be valid!
        void setInvalid();

        // Return true if valid. Otherwise, return false.
        bool isValid() const { return m_valid; }

        // The previous one will change to be valid when this task submitted.
        // By default, do not want to do it.
        void setWantToInvalidPreviousOneWhenSubmitted(bool val) {
            m_wantToInvalidPreviousOneWhenSubmitted = val;
        }
        bool wantToInvalidPreviousOneWhenSubmitted() {
            return m_wantToInvalidPreviousOneWhenSubmitted;
        }

        virtual void execute() override final;
        virtual bool isExecuting() const override final { return m_executing; }

    protected:
        // Do execute. Return true if finished. Return false if not finished.
        virtual bool onExecute() = 0;

    private:
        const AsynchronousDeferredTask::EPriority m_priority;
        bool m_valid;
        bool m_wantToInvalidPreviousOneWhenSubmitted;
        bool m_executing;
    };
    
}
